<template>
    <el-form ref="formRef" :model="form" labelWidth="120px" label-suffix="：">
        <el-steps :active="active">
            <template v-for="(step, index) in steps" :key="index">
                <el-step>
                    <template #title>
                        <span class="step-title" @click="active = step.value">{{ step.title }}</span>
                    </template>
                </el-step>
            </template>
        </el-steps>

        <div v-show="active === 1" class="step1">
            <el-form-item label="节点名称">
                <el-input v-model="form.nodeName"/>
            </el-form-item>
            <el-form-item label="节点ID">
                <el-input v-model="form.typeConcatName" disabled></el-input>
            </el-form-item>
            <el-form-item label="API URL">
                <el-row>
                    <el-col :span="6">
                        <el-select v-model="form.method">
                            <el-option label="GET" value="GET"/>
                            <el-option label="POST" value="POST"/>
                        </el-select>
                    </el-col>
                    <el-col :span="18">
                        <el-input v-model="form.url"/>
                    </el-col>
                </el-row>
            </el-form-item>
            <el-form-item label="返回数据字段">
                <el-input v-model="form.result.name"/>
            </el-form-item>
            <el-form-item label="入参编码">
                <el-radio-group v-model="form.inParamEncoding">
                    <el-radio :label="false">否</el-radio>
                    <el-radio :label="true">Base64编码</el-radio>
                </el-radio-group>
            </el-form-item>
            <el-form-item label="出参编码">
                <el-radio-group v-model="form.outParamEncoding">
                    <el-radio :label="false">否</el-radio>
                    <el-radio :label="true">Base64编码</el-radio>
                </el-radio-group>
            </el-form-item>
            <el-form-item label="备注">
                <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"/>
            </el-form-item>
            <dialog-footer @cancel="cancel" @ok="submitForm" ok-text="保存">
                <el-button type="success" @click="active = 2">下一步</el-button>
            </dialog-footer>
        </div>
        <div v-show="active === 2" class="step2">
            <el-form-item>
                <el-button type="primary" @click="addHeader">添加Header头</el-button>
                <el-table :data="form.headers.header" style="width: 100%">
                    <el-table-column prop="name" label="Header名" width="160">
                        <template #default="scope">
                            <el-input v-model="scope.row.name" placeholder="请输入Header名"></el-input>
                        </template>
                    </el-table-column>
                    <el-table-column prop="value" label="参数值" width="370">
                        <template #default="scope">
                            <el-input v-model="scope.row.value" type="textarea" placeholder="请输入参数值"></el-input>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" width="80">
                        <template #default="scope">
                            <el-button type="text" size="small" @click="removeHeader(scope.$index)">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-form-item>
            <el-form-item v-if="form.switchForm === 'N' && form.method === 'POST'" label="bodyContent">
                <el-button type="primary" @click="addBodyField">添加bodyContent参数</el-button>
                <el-table :data="form.bodyField" style="width: 100%">
                    <el-table-column prop="name" label="参数名" width="320">
                        <template #default="scope">
                            <el-input v-model="scope.row.name" placeholder="请输入参数名"></el-input>
                        </template>
                    </el-table-column>
                    <el-table-column prop="value" label="参数值" width="370">
                        <template #default="scope">
                            <el-input v-model="scope.row.value" placeholder="请输入参数值"></el-input>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" width="80">
                        <template #default="scope">
                            <el-button type="text" size="small" @click="removeBodyField(scope.$index)">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-form-item>
            <el-form-item v-if="form.switchForm === 'Y' && form.method === 'POST'" label="bodyContent">
                <el-button type="primary" @click="addJson">入参（json）</el-button>
                <el-button type="primary" @click="formatJson">json格式化</el-button>
                <monaco-editor style="width:100%; height:400px; margin-top: 5px"
                               v-model:value="form.bodyContent"
                               @changeTextArea="changeTextArea"
                               ref="monacoEditorRef"
                               class="script-textarea"
                               language='json'
                ></monaco-editor>
            </el-form-item>
            <el-form-item label="切换表单" v-if="form.method === 'POST'">
                <el-switch v-model="form.switchForm" active-value="Y" inactive-value="N" @change="switchFormChange"/>
            </el-form-item>
            <dialog-footer @cancel="cancel" @ok="submitForm" ok-text="保存">
                <el-button type="success" @click="active = 1">上一步</el-button>
                <el-button type="success" @click="active = 3">下一步</el-button>
            </dialog-footer>
        </div>

        <div v-show="active === 3" class="step3">
            <el-form-item label="字段">
                <div style="margin-bottom: 10px;">
                    <el-button
                        type="primary"
                        size="small"
                        @click="addField"
                    >新增字段</el-button>
                    <el-button
                        type="danger"
                        size="small"
                        @click="batchDelete"
                        :disabled="selectedRows.length === 0"
                    >删除选中</el-button>
                    <el-button
                        type="primary"
                        size="small"
                        @click="jsonDialogVisible = true"
                    >从结果Json中自动分析</el-button>
                </div>
                <el-table :data="form.fields.field" style="width: 100%" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="30"/>
                    <el-table-column label="序号" width="50" header-align="center" align="center">
                        <template #default="scope">
                            {{ scope.$index + 1 }}
                        </template>
                    </el-table-column>
                    <el-table-column prop="name" label="字段名称" width="160">
                        <template #default="scope">
                            <el-input v-model="scope.row.name"  placeholder="请输入字段名称"></el-input>
                        </template>
                    </el-table-column>
                    <el-table-column prop="type" label="字段类型" width="150">
                        <template #default="scope">
                            <el-select v-model="scope.row.type">
                            </el-select>
                        </template>
                    </el-table-column>
                    <el-table-column prop="length" label="长度" width="120">
                        <template #default="scope">
                            <el-input v-model="scope.row.length" placeholder="请输入长度"></el-input>
                        </template>
                    </el-table-column>
                    <el-table-column prop="description" label="参数说明" width="240">
                        <template #default="scope">
                            <el-input v-model="scope.row.description" placeholder="请输入参数说明"></el-input>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" width="80">
                        <template #default="scope">
                            <el-button
                                type="danger"
                                size="small"
                                @click="deleteField(scope.$index)"
                            >删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
                <div class="tip">说明：配置API的输入字段方便后续节点配置字段映射时使用</div>
            </el-form-item>
            <dialog-footer @cancel="cancel" @ok="submitForm" ok-text="保存">
                <el-button type="success" @click="active = 2">上一步</el-button>
            </dialog-footer>
        </div>

    </el-form>

    <el-dialog
        v-model="jsonDialogVisible"
        title="输入结果JSON"
        width="60%"
        class="custom-dialog"
    >
        <div class="dialog-content">
            <el-input
                v-model="form.dialogJson"
                type="textarea"
                :autosize="{ minRows: 20, maxRows: 30 }"
                style="width:100%; margin-top: 5px; height: 60vh"
                class="large-textarea"
            />
        </div>
        <template #footer>
            <el-button @click="jsonDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="analyzeJson">解析</el-button>
        </template>
    </el-dialog>

</template>

<script setup>
import {defineComponent, ref, onMounted, reactive, watch, nextTick} from 'vue';
import {flowServiceStore} from '@data/store/flow';
import monacoEditor from "../disposition/monaco-editor.vue";

const flowCount = flowServiceStore();
import {storeToRefs} from 'pinia';
import {ElMessage} from "element-plus";

const {flowData} = storeToRefs(flowCount);

defineComponent({
    name: 'RestInput',
});
const props = defineProps({
    detailObject: {
        type: Object,
        default: () => {
        },
    },
})

const steps = ref([
    { value: 1, title: '基础属性' },
    { value: 2, title: '输入参数' },
    { value: 3, title: '输出字段' }
]);
const active = ref(1);
const monacoEditorRef = ref(null);
const jsonDialogVisible = ref(false);
const loading = ref(false);

const form = reactive({
    nodeName: '',
    name: '',
    type: 'RestInput',
    distribute: 'Y',
    copies: 1,
    method: 'GET',
    inParamEncoding: '',
    outParamEncoding: '',
    url: '',
    remark: '',

    applicationType: '',
    dynamicMethod: 'N',
    result: {
        name: 'result'
    },

    headers: {
        header: [
            {
                name: '',
                value: '',
            }
        ]
    },

    dialogJson: '',
    fields: {
        field: [
            {
                name: '',
                type: '',
                length: '',
                description: '',
            }
        ]
    },

    GUI: {
        xloc: 1,
        yloc: 1,
        draw: 'Y'
    }
});

const emit = defineEmits(['cancel']);

onMounted(() => {
    form.nodeName = flowData.value[props.detailObject.id]?.nodeName || props.detailObject.data.label;
    form.method = flowData.value[props.detailObject.id]?.method || 'GET';
    form.url = flowData.value[props.detailObject.id]?.url || '';
    form.inParamEncoding = flowData.value[props.detailObject.id]?.inParamEncoding || '';
    form.outParamEncoding = flowData.value[props.detailObject.id]?.outParamEncoding || '';
    form.remark = flowData.value[props.detailObject.id]?.remark || '';
    form.name = props.detailObject.id;
    form.typeConcatName = `${props.detailObject.id}(${form.type}-${props.detailObject.id})`;

    form.applicationType = flowData.value[props.detailObject.id]?.applicationType || '';
    form.dynamicMethod = flowData.value[props.detailObject.id]?.dynamicMethod || 'N';
    form.result = flowData.value[props.detailObject.id]?.result || {
        name: 'result'
    };

    form.headers.header = flowData.value[props.detailObject.id]?.headers?.header || [{
        name: '',
        value: '',
    }];
    if(form.method === 'POST'){
        form.switchForm = flowData.value[props.detailObject.id]?.switchForm || 'N';
        form.bodyContent = flowData.value[props.detailObject.id]?.bodyContent || '';
        if(form.switchForm === 'N') {
            form.bodyField = flowData.value[props.detailObject.id]?.bodyField || [];
        }
    }

    form.fields.field = flowData.value[props.detailObject.id]?.fields?.field || [{
        name: '',
        type: '',
        length: '',
        description: '',
    }];

    form.distribute = flowData.value[props.detailObject.id]?.distribute || 'Y';

})

watch(
    () => form.switchForm,
    (newVal) => {
        if(newVal === 'Y') {
            nextTick(() => {
                if(monacoEditorRef.value) {
                    monacoEditorRef.value.setData(form.bodyContent);
                }
            })
        }
    },
    { immediate: true }
)

const addHeader = () => {
    // 确保headers.header数组存在
    if (!form.headers.header) {
        form.headers.header = [];
    }
    form.headers.header.push({
        name: '',
        value: '',
    });
}
const removeHeader = (index) => {
    form.headers.header.splice(index, 1);
}
const switchFormChange = (value) => {
    if(value === 'N'){
        form.bodyField = [{
            name: '',
            value: '',
        }];
        form.applicationType = 'application/x-www-form-urlencoded';
    } else {
        form.bodyContent = '';
        form.bodyContentValue = '';
        form.applicationType = 'application/json;charset=utf-8';
        nextTick(() => {
            if(monacoEditorRef.value) {
                monacoEditorRef.value.setData(form.bodyContent);
            }
        })
    }
}
const addBodyField = () => {
    if (!form.bodyField) {
        form.bodyField = [];
    }
    form.bodyField.push({
        name: '',
        value: '',
    });
}
const removeBodyField = (index) => {
    form.bodyField.splice(index, 1);
}

// 类型长度映射表
const typeLengthMap = {
    'String': 255,
    'Integer': 10,
    'Double': 16,
    'Boolean': 1,
    'Array': 0
}
// 获取默认字段长度
const getDefaultLength = (type) => {
    return typeLengthMap[type] || 0;
}
const addJson = () => {
    console.log('addJson');
}
const formatJson = () => {
    console.log('formatJson');
    if(!form.bodyContentValue) return
    const parsed = JSON.parse(form.bodyContentValue);
    form.bodyContentValue = JSON.stringify(parsed, null, 2);
    monacoEditorRef.value.setData(form.bodyContentValue)
}
const analyzeJson = () => {
    try {
        // 1. 校验并解析JSON
        if (!form.dialogJson.trim()) {
            ElMessage.warning('请输入JSON内容');
            return;
        }
        const jsonData = JSON.parse(form.dialogJson);

        // 递归解析方法
        const extractFields = (data, path = '') => {
            let fields = [];

            // 处理对象
            const processObject = (obj, currentPath) => {
                for (const [key, value] of Object.entries(obj)) {
                    const newPath = currentPath ? `${currentPath}.${key}` : key;
                    fields = fields.concat(extractFields(value, newPath));
                }
            };

            // 处理数组
            const processArray = (arr, currentPath) => {
                arr.forEach((item, index) => {
                    const elementPath = `${currentPath}[${index}]`;
                    fields = fields.concat(extractFields(item, elementPath));

                    // 标记数组类型（如果元素是基础类型）
                    if (typeof item !== 'object' && !fields.some(f => f.name === currentPath)) {
                        fields.push(createField(currentPath, getType(item), true));
                    }
                });
            };

            // 创建字段对象
            const createField = (name, type, isArray = false) => ({
                name: isArray ? name : path,
                type: isArray ? 'Array' : type,
                length: getDefaultLength(type),
                description: isArray ? `数组类型，元素类型：${type}` : ''
            });

            // 类型判断
            const getType = (value) => {
                if (Array.isArray(value)) return 'Array';
                if (value === null) return 'Null';
                if (typeof value === 'object') return 'Object';
                return typeof value === 'number'
                    ? (Number.isInteger(value) ? 'Integer' : 'Double')
                    : typeof value === 'boolean' ? 'Boolean' : 'String';
            };

            // 主逻辑
            const type = getType(data);

            if (type === 'Object') {
                for (const [key, value] of Object.entries(data)) {
                    // 修改点1：只保留当前层级的key作为路径
                    fields = fields.concat(extractFields(value, key));
                }
            } else if (type === 'Array' && data.length > 0) {
                // 修改点2：处理数组时直接取元素类型
                const elementType = getType(data[0]);
                fields.push({
                    name: path,
                    type: 'Array',
                    length: 0,
                    description: `数组类型，元素类型：${elementType}`
                });
                // 添加数组元素字段（如果需要）
                if (elementType === 'Object') {
                    fields = fields.concat(extractFields(data[0], path));
                }
            } else {
                // 修改点3：直接使用当前key作为字段名
                if (path) {
                    fields.push({
                        name: path,
                        type: type,
                        length: getDefaultLength(type),
                        description: ''
                    });
                }
            }
            return fields;
        }

        // 去重处理
        const uniqueFields = Array.from(new Set(
            extractFields(jsonData)
                .map(f => JSON.stringify(f))
        )).map(f => JSON.parse(f));

        if (uniqueFields.length > 0) {
            form.fields.field = uniqueFields;
            ElMessage.success(`解析成功，共发现 ${uniqueFields.length} 个字段`);
        } else {
            ElMessage.warning('未检测到有效字段');
        }
    } catch (e) {
        ElMessage.error(`解析失败: ${e.message}`);
    }
    jsonDialogVisible.value = false;
}

const changeTextArea = (value) => {
    console.log('changeTextArea',value)
    form.bodyContentValue = value;
}

const selectedRows = ref([])
const addField = () => {
    form.fields.field.push({
        name: '',
        rename: '',
        length: '',
        description: '',
    });
}
// 处理选择变化
const handleSelectionChange = (val) => {
    selectedRows.value = val
}
// 批量删除方法
const batchDelete = () => {
    if (selectedRows.value.length === 0) return
    // 获取选中项的索引
    const indexes = selectedRows.value.map(row =>
        form.fields.field.indexOf(row)
    ).sort((a,b) => b - a) // 倒序排列避免删除错位
    // 执行删除
    indexes.forEach(index => {
        form.fields.field.splice(index, 1)
    })
    // 清空选中
    selectedRows.value = []
}
// 修改删除方法
const deleteField = (index) => {
    form.fields.field.splice(index, 1);
}


const submitForm = () => {
    form.fields.field.forEach(fieldItem => {
      form.fieldList.push(fieldItem);
    });
    if(form.switchForm === 'Y'){
        form.bodyContent = form.bodyContentValue;
    } else if (form.switchForm === 'N'){
        console.log(form.switchForm);
        form.bodyContent = form.bodyField
            .map(param =>
                `${encodeURIComponent(param.name)}=${encodeURIComponent(param.value)}`
            )
            .join('&');
    }

    flowCount.setFlowData(
        {
            ...flowData.value,
            [props.detailObject.id]: {
                ...form,
                name: `${form.type}-${form.name}`,
            }
        }
    )
  // 触发数据更新事件
  // emit('update-data', {
  //   id: props.detailObject.id,
  //   data: form
  // });
    console.log(flowData.value);
    emit('cancel');
}
const cancel = () => {
    console.log(flowData.value);
    emit('cancel');
}

const toReader = () => {

}

const parseSql = () => {
}

</script>

<style scoped>
.tip {
    color: #999;
    font-size: 12px;
    margin-top: 4px;
    line-height: 0.5;
}
.custom-dialog {
    /* 限制弹窗最大高度 */
    max-height: 80vh;
    display: flex;
    flex-direction: column;
}
.dialog-content {
    flex: 1;
    min-height: 200px;
    overflow: hidden;
    display: flex;
}
.large-textarea {
    flex: 1;
    font-family: Monaco, Consolas, 'Courier New', monospace;
    font-size: 14px;
    line-height: 1.5;
}
/* 如果需要更精确控制高度 */
:deep(.large-textarea) textarea {
    height: 100% !important;
    min-height: 300px !important; /* 保留最小高度 */
    max-height: calc(80vh - 120px) !important;
}
</style>